package com.alibaba.algo.utils;

import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Base64;

/**
 * @ClassName FileUtils
 * @Description 文件工具类
 * @Author wangke
 * @Date 2021/8/19 11:28
 */
@Slf4j
@Component
public class FileUtils {

    private static Float scale;

    private static Float quality;

    private static Integer size;

    private static String unit;

    //图片文件过期时间(单位：秒)
    private static Integer fileExpireTime;

    @Value("${compress.scale:0.3f}")
    public void setScale(Float scale) {
        FileUtils.scale = scale;
    }

    @Value("${compress.quality:1f}")
    public void setQuality(Float quality) {
        FileUtils.quality = quality;
    }

    @Value("${compress.size:5}")
    public void setSize(Integer size) {
        FileUtils.size = size;
    }
    @Value("${compress.unit:MB}")
    public void setUnit(String unit) {
        FileUtils.unit = unit;
    }

    @Value("${compress.expireTime:1440}")
    public void setFileExpireTime(Integer fileExpireTime) {
        FileUtils.fileExpireTime = fileExpireTime;
    }

    public static Integer getFileExpireTime() {
        return fileExpireTime;
    }

    /**
     * multipartFile转file
     * @param file
     * @return
     * @throws Exception
     */
    public static File multipartFile2File(MultipartFile file) throws Exception{
        File toFile = null;
        if(file.equals("") || file.getSize() <= 0){
            file = null;
        }else{
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStream2File(ins,toFile);
            ins.close();
        }
        return toFile;
    }

    public static void inputStream2File(InputStream ins,File file){
        try{
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while((bytesRead = ins.read(buffer,0,8192)) != -1){
                os.write(buffer,0,bytesRead);
            }
            os.close();
            ins.close();
        }catch(Exception e){
            log.error("FileUtils inputStream2File error:{}",e);
        }
    }

    /**
     * 压缩图片文件
     * @param file
     * @return
     */
    public static byte[] compressFile(MultipartFile file){
        if(ObjectUtils.isEmpty(scale)){
            scale = 0.3f;
        }
        if(ObjectUtils.isEmpty(quality)){
            quality = 1.0f;
        }
        byte[] result = null;
        String originalFilename = file.getOriginalFilename();//原文件名
        String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);//获取后缀
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//io流
        //压缩图片流
        try {
            Thumbnails.of(file.getInputStream()).scale(scale)//压缩尺寸 范围（0.00--1.00）
                    .outputQuality(quality)//压缩质量 范围（0.00--1.00）
                    .outputFormat(ext)//输出图片后缀
                    .toOutputStream(byteArrayOutputStream);
            if(null != byteArrayOutputStream){
                log.debug("compressFile byteArrayOutputStream size:{}",byteArrayOutputStream.size());
                result = byteArrayOutputStream.toByteArray();
            }else{
                log.error("compressFile error,byteArrayOutputStream is null");
            }
        } catch (Exception e) {
            log.error("compressFile error:{}",e);
        }finally{
            return result;
        }
    }

    /**
     * 下载文件至项目中来验证文件是否正常
     * @param fileBase64
     * @param fileName
     * @param fileSuffix
     */
    public static void downloadAndCheckImg(String fileBase64,String fileName,String fileSuffix){
        log.debug("downloadAndCheckImg fileName:{},fileSuffix:{}",fileName,fileSuffix);
        if(ObjectUtils.isEmpty(fileBase64) || ObjectUtils.isEmpty(fileName) || ObjectUtils.isEmpty(fileSuffix)){
            log.debug("downloadAndCheckImg param is illegal");
            return;
        }
        byte[] byteArray = Base64.getDecoder().decode(fileBase64);
        InputStream is = new ByteArrayInputStream(byteArray);
        int len = 0;
        try {
            OutputStream os = new FileOutputStream(new File(fileName+fileSuffix));
            //开始读取
            while ((len = is.read(byteArray)) != -1) {
                os.write(byteArray, 0, len);
            }
            //关闭链接
            os.close();
        } catch (FileNotFoundException e) {
            log.error("downloadAndCheckImg FileNotFoundException:{}",e);
        } catch (IOException e) {
            log.error("downloadAndCheckImg IOException:{}",e);
        }
    }

    /**
     * 判断文件大小
     * @param len 文件大小
     * @return
     */
    public static boolean checkFileSize(Long len){
        if(ObjectUtils.isEmpty(size)){
            size = 5;
        }
        if(ObjectUtils.isEmpty(unit)){
            unit = "MB";
        }
        double fileSize = 0;
        if("B".equals(unit.toUpperCase())){
            fileSize = (double)len;
        }else if("KB".equals(unit.toUpperCase())){
            fileSize = (double)len/1024;
        }else if("MB".equals(unit.toUpperCase())){
            fileSize = (double)len/1048576;
        }else if("GB".equals(unit.toUpperCase())){
            fileSize = (double)len/1073741824;
        }
        if(fileSize > size){
            return false;
        }
        return true;
    }
}
